package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.system.baidu.BaiduClient;
import com.ruoyi.system.domain.Lesson;
import com.ruoyi.system.domain.Sign;
import com.ruoyi.system.domain.Student;
import com.ruoyi.system.dto.FaceSignParam;
import com.ruoyi.system.dto.LocationSignParam;
import com.ruoyi.system.mapper.LessonMapper;
import com.ruoyi.system.mapper.SignMapper;
import com.ruoyi.system.mapper.StudentMapper;
import com.ruoyi.system.service.SignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SignServiceImpl implements SignService {
    @Autowired
    private SignMapper signMapper;
    @Autowired
    private LessonMapper lessonMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private BaiduClient baiduClient;

    @Override
    public void signWithLocation(LocationSignParam locationSignParam, Student student) {
        boolean exists = this.signMapper.countTodayByLessonIdAndStudentId(locationSignParam.getLessonId(), student.getStudentId()) > 0;
        if (exists) {
            return;
        }
        Lesson lesson = this.lessonMapper.selectById(locationSignParam.getLessonId());
        LocalDateTime startTime = LocalDateTime.from(lesson.getSignStartTime().toInstant().atZone(ZoneId.systemDefault()));
        LocalDateTime endTime = LocalDateTime.from(lesson.getSignEndTime().toInstant().atZone(ZoneId.systemDefault()));
        LocalDateTime now = LocalDateTime.now();
        if (startTime.isAfter(now)) {
            throw new RuntimeException("还没到打卡时间");
        }
        //允许迟到打卡
//        if (endTime.isBefore(now)) {
//            throw new RuntimeException("已经超过打卡时间");
//        }


        Sign sign = new Sign();
        sign.setLessonId(locationSignParam.getLessonId());
        sign.setStudentId(student.getStudentId());
        sign.setSignType(1);
        sign.setSignTime(new Date());
        sign.setSignLocationLat(locationSignParam.getLat());
        sign.setSignLocationLong(locationSignParam.getLng());
        this.signMapper.insert(sign);
    }

    @Override
    public void signWithFace(FaceSignParam faceSignParam, Student student) {
        boolean exists = this.signMapper.countTodayByLessonIdAndStudentId(faceSignParam.getLessonId(), student.getStudentId()) > 0;
        if (exists) {
            return;
        }
        Lesson lesson = this.lessonMapper.selectById(faceSignParam.getLessonId());
        LocalDateTime startTime = LocalDateTime.from(lesson.getSignStartTime().toInstant().atZone(ZoneId.systemDefault()));
        LocalDateTime endTime = LocalDateTime.from(lesson.getSignEndTime().toInstant().atZone(ZoneId.systemDefault()));
        LocalDateTime now = LocalDateTime.now();
        if (startTime.isAfter(now)) {
            throw new RuntimeException("还没到打卡时间");
        }
        //允许迟到打卡
//        if (endTime.isBefore(now)) {
//            throw new RuntimeException("已经超过打卡时间");
//        }

        boolean match = this.baiduClient.match(student.getSignPhoto().replace("data:image/png;base64,", ""), faceSignParam.getPhotoBase64().replace("data:image/png;base64,", ""));
        if (!match) {
            throw new RuntimeException("人脸特征不符合");
        }

        Sign sign = new Sign();
        sign.setLessonId(faceSignParam.getLessonId());
        sign.setStudentId(student.getStudentId());
        sign.setSignType(2);
        sign.setSignTime(new Date());
        sign.setSignLocationLat("");
        sign.setSignLocationLong("");
        this.signMapper.insert(sign);
    }

    @Override
    public List<Sign> list(Integer studentId) {
        LambdaQueryWrapper<Sign> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Sign::getStudentId, studentId);
        List<Sign> signList = this.signMapper.selectList(wrapper);
        List<Integer> lessonIds = signList.stream()
                .map(Sign::getLessonId)
                .collect(Collectors.toList());
        if (!lessonIds.isEmpty()) {
            Map<Integer, Lesson> lessonIdLessonMap = this.lessonMapper.selectBatchIds(lessonIds)
                    .stream()
                    .collect(Collectors.toMap(Lesson::getLessonId, e -> e));

            for (Sign sign : signList) {
                String lessonName = lessonIdLessonMap.getOrDefault(sign.getLessonId(), new Lesson())
                        .getLessonName();
                sign.setLessonName(lessonName);
            }
        }
        return signList;
    }
}
